//! # 死信队列模块
//!
//! 重新导出 rustcloud-resilience 模块的死信队列功能，
//! 为 rustcloud-stream 提供统一的死信队列机制。
//! 
//! 通过这种方式保持向后兼容性，同时使用公共功能模块。

// 重新导出 rustcloud-resilience 的死信队列功能
pub use rustcloud_resilience::dead_letter::*;

// 为流处理定制的死信队列实现
use async_trait::async_trait;
use crate::core::{StreamMessage, StreamResult};

/// 流处理专用死信队列
pub struct StreamDeadLetterQueue {
    /// 底层死信队列
    inner: Box<dyn rustcloud_resilience::dead_letter::DeadLetterQueue>,
    /// 流主题前缀
    stream_topic_prefix: String,
}

impl StreamDeadLetterQueue {
    /// 创建新的流死信队列
    pub fn new(
        inner: Box<dyn rustcloud_resilience::dead_letter::DeadLetterQueue>,
        stream_topic_prefix: String,
    ) -> Self {
        Self {
            inner,
            stream_topic_prefix,
        }
    }

    /// 发送流消息到死信队列
    pub async fn send_stream_message(
        &self,
        message: &StreamMessage,
        error: &crate::error::StreamError,
    ) -> StreamResult<()> {
        // 构造死信消息
        let dead_letter = rustcloud_resilience::dead_letter::DeadLetterMessage::new(
            format!("{}:{}", self.stream_topic_prefix, message.topic()),
            message.payload().clone(),
            error.to_string(),
            std::collections::HashMap::new(),
        );

        self.inner.send(dead_letter).await
            .map_err(|e| crate::error::StreamError::DeadLetter(e.to_string()))
    }

    /// 获取流死信统计信息
    pub async fn get_stream_stats(&self) -> StreamResult<StreamDeadLetterStats> {
        let stats = self.inner.get_stats().await
            .map_err(|e| crate::error::StreamError::DeadLetter(e.to_string()))?;

        Ok(StreamDeadLetterStats {
            total_messages: stats.total_messages,
            pending_messages: stats.pending_messages,
            processed_messages: stats.processed_messages,
            failed_messages: stats.failed_messages,
            stream_topic_prefix: self.stream_topic_prefix.clone(),
        })
    }
}

#[async_trait]
impl rustcloud_resilience::dead_letter::DeadLetterQueue for StreamDeadLetterQueue {
    async fn send(
        &self,
        message: rustcloud_resilience::dead_letter::DeadLetterMessage,
    ) -> rustcloud_resilience::dead_letter::Result<()> {
        self.inner.send(message).await
    }

    async fn receive(&self) -> rustcloud_resilience::dead_letter::Result<
        Option<rustcloud_resilience::dead_letter::DeadLetterMessage>
    > {
        self.inner.receive().await
    }

    async fn get_stats(&self) -> rustcloud_resilience::dead_letter::Result<
        rustcloud_resilience::dead_letter::DeadLetterStats
    > {
        self.inner.get_stats().await
    }

    async fn clear(&self) -> rustcloud_resilience::dead_letter::Result<()> {
        self.inner.clear().await
    }
}

/// 流死信队列统计信息
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
pub struct StreamDeadLetterStats {
    /// 总消息数
    pub total_messages: u64,
    /// 待处理消息数
    pub pending_messages: u64,
    /// 已处理消息数
    pub processed_messages: u64,
    /// 处理失败消息数
    pub failed_messages: u64,
    /// 流主题前缀
    pub stream_topic_prefix: String,
}

/// 流死信队列配置
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
pub struct StreamDeadLetterConfig {
    /// 最大队列大小
    pub max_queue_size: usize,
    /// 消息保留时间（秒）
    pub retention_seconds: u64,
    /// 是否启用自动清理
    pub enable_auto_cleanup: bool,
    /// 流主题前缀
    pub stream_topic_prefix: String,
}

impl Default for StreamDeadLetterConfig {
    fn default() -> Self {
        Self {
            max_queue_size: 10000,
            retention_seconds: 3600 * 24 * 7, // 7天
            enable_auto_cleanup: true,
            stream_topic_prefix: "stream".to_string(),
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    
    #[test]
    fn test_stream_dead_letter_config_default() {
        let config = StreamDeadLetterConfig::default();
        assert_eq!(config.max_queue_size, 10000);
        assert_eq!(config.retention_seconds, 3600 * 24 * 7);
        assert!(config.enable_auto_cleanup);
        assert_eq!(config.stream_topic_prefix, "stream");
    }

    #[test]
    fn test_stream_dead_letter_stats_serialization() {
        let stats = StreamDeadLetterStats {
            total_messages: 100,
            pending_messages: 10,
            processed_messages: 80,
            failed_messages: 10,
            stream_topic_prefix: "test-stream".to_string(),
        };

        let json = serde_json::to_string(&stats).unwrap();
        let deserialized: StreamDeadLetterStats = serde_json::from_str(&json).unwrap();
        
        assert_eq!(deserialized.total_messages, 100);
        assert_eq!(deserialized.stream_topic_prefix, "test-stream");
    }
}